package cgs_mingdao

import (
	"bytes"
	"encoding/json"
	"fmt"
	"cgs-server/helper"
	"cgs-server/server"
	"cgs-server/server/assets/cgs_worksheet"
	"cgs-server/server/base"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
)

func init() {
	server.Get("/api/Cgs/md/GetApp", GetApp, "GetApp",server.None)
	server.Post("/api/Cgs/md/GetWorksheetInfo",GetWorkSheet,"GetWorkSheet",server.None)
	server.Post("/api/Cgs/md/SaveMDStruct",SaveMDStruct,"Save Struct",server.None)
}
/**
获取明道APP信息（分类及表单）
 */
func GetApp(w http.ResponseWriter, r *http.Request){
	//URL,AppKey,Sign
	//url :="http://39.98.119.248:8880/api/v1/open/app/get"
	//sign :="MWE3ZGFiMGQxODZjMWM1NThkMzIyZDAzMDY4YzdlNWIzZjc0YjNlNWE4MmI4NzkyOGRlMWI4ZGE0ODlmODg3Ng=="
	//appKey :="4d5c9be0052ba266"
	url := r.FormValue("url")
	sign := r.FormValue("sign")
	appKey := r.FormValue("appKey")

	if url == "" || sign == "" || appKey == "" {
		_, _ = helper.WriteJSON(w, server.Fail("url, sign, appKey is required"))
		return
	}
	url = getBaseUrl(url) + "/v1/open/app/get"

	resp,err:=http.Get(url+"?appKey="+appKey+"&sign="+sign)
	if err!=nil{
		fmt.Println(err)
	}
	var s MDApp
	bodyC, _ := ioutil.ReadAll(resp.Body)
	_ = json.Unmarshal(bodyC, &s)
	s.Data.FilterItem()
	_, _ = helper.WriteJSON(w, server.OK("Get successfully!").WithData(s.Data))
}
/**
获取明道工作表信息
 */
func GetWorkSheet(w http.ResponseWriter, r *http.Request){
	//url:="http://39.98.119.248:8880/api/v2/open/worksheet/getWorksheetInfo"
	//sign :="MWE3ZGFiMGQxODZjMWM1NThkMzIyZDAzMDY4YzdlNWIzZjc0YjNlNWE4MmI4NzkyOGRlMWI4ZGE0ODlmODg3Ng=="
	//appKey :="4d5c9be0052ba266"
	//workSheetID:="5eb9f1b258627408e8be89fd"

	url := r.FormValue("url")
	sign := r.FormValue("sign")
	appKey := r.FormValue("appKey")
	workSheetID := r.FormValue("worksheetId")

	if url == "" || sign == "" || appKey == "" {
		_, _ = helper.WriteJSON(w, server.Fail("url, sign, appKey is required"))
		return
	}
	url = getBaseUrl(url) + "/v2/open/worksheet/getWorksheetInfo"

	params:=map[string]string{"appKey":appKey,"sign":sign,"workSheetID":workSheetID}
	jsonParams, _ :=json.Marshal(params)
	resp,err:=http.Post(url,"application/json",bytes.NewBuffer(jsonParams))
	if err!=nil{
		fmt.Println(err)
	}
	body,_:=ioutil.ReadAll(resp.Body)
	var s MDWorkSheetInfo
	json.Unmarshal(body,&s)
	_, _ = helper.WriteJSON(w, server.OK("Get successfully!").WithData(s.Data))

}
/**
	保存数据同步基础信息
 */
func SaveMDStruct(w http.ResponseWriter, r *http.Request){
	//viewID:="5eb9f1b258627408e8be89fe"
	//url:="http://39.98.119.248:8880/api"
	//appKey:=""
	//sign:=""
	//wsName:=""
	//visualData
	//gen config and fields
	r.Body = http.MaxBytesReader(w, r.Body, int64(100<<20))
	s, _ := ioutil.ReadAll(r.Body) //把  body 内容读入字符串 s
	data := &bson.M{}
	err := helper.FromJSON(s, data)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	//save _WorksheetInfo
	db, err := server.Mongo()
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Result{
			Code: 300,
			Msg:  err.Error(),
		})
		return
	}

	//doc:=parseWorkSheet(*data)
	wsInfo:=parseWorkSheetInfo(*data)
	dataUserModel := base.GenerateDataUserModel(wsInfo, r)
	wsService := cgs_worksheet.NewWorksheetService()
	err = wsService.Save(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	//save _MDWorkSheet
	mdDoc:=parseMDWorksheet(*data,wsInfo)
	_, err = db.InsertOne(server.CgsMDWorksheetInfoCollectionName, mdDoc)
	//fmt.Println(mdDoc)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	// 同步一下数据
	server.Sync()

	_, _ = helper.WriteJSON(w, server.OK("Save successfully."))
}
func parseMDWorksheet(data bson.M, wsInfo *cgs_worksheet.WorksheetInfo) bson.M {
	id := primitive.NewObjectID()
	mdDoc:=bson.M{
		"id": id,
		"baseUrl": getBaseUrl(data["baseUrl"].(string)),
		"appKey":data["appKey"],
		"controls":data["controls"],
		"sign":data["sign"],
		"appId":data["appId"],
		"worksheetId":data["worksheetId"],
		"viewId":data["viewId"],
		"cgsWsId":wsInfo.Id,
		"createTime":time.Now().In(server.CstZone),
		"updateTime":time.Now().In(server.CstZone),
	}
	return mdDoc
}
func parseWorkSheetInfo(data bson.M) *cgs_worksheet.WorksheetInfo {
	wsInfo := &cgs_worksheet.WorksheetInfo{}
	id := primitive.NewObjectID()
	wsInfo.Id=id
	wsInfo.WsName=data["wsName"].(string)
	wsInfo.UpdateTime=time.Now().In(server.CstZone)
	isDeleted:=0
	wsInfo.IsDeleted=&isDeleted
	wsCollection := "ws" + id.Hex()
	wsInfo.WsCollection=wsCollection
	var visualData=data["visualData"].([]interface{})
	var paramSlice []string
	for _, param := range visualData {
		paramSlice = append(paramSlice, param.(string))
	}
	wsInfo.VisualData=paramSlice
	wsInfo.CreateTime=time.Now().In(server.CstZone)
	controls:=data["controls"].([]interface{})
	wsInfo.Fields=createWSFields(controls)
	wsInfo.Config=createConfigStr(controls)
	return wsInfo

}
func parseWorkSheet(data bson.M) bson.M {
	//wsInfo := &cgs_worksheet.WorksheetInfo{}
	id := primitive.NewObjectID()
	doc := bson.M{
		"id": id,
		"wsName": data["wsName"],
		//"fields": fields,
		//"config": data["config"],TODO
		"updateTime": time.Now().In(server.CstZone),
		"isDeleted": 0,  // 用逻辑删除比较好， 0未删除，1已删除
	}
	controls:=data["controls"].([]interface{})
	//var config =make(map[string]interface{})
	var config =newConfig(controls)
	fields := createFields(data)
	doc["fields"] = fields
	configStr, _ := json.Marshal(config)
	str := string(configStr)
	doc["config"] = str
	wsCollection := "ws" + id.Hex()
	doc["wsCollection"] = wsCollection
	doc["createTime"] = time.Now().In(server.CstZone)
	doc["visualData"] = data["visualData"] // 所属应用
	return doc
}
func createWSFields(controls []interface{}) []*cgs_worksheet.Field {
	var fields []*cgs_worksheet.Field
	for _, v := range controls {
		m := v.(map[string]interface{})
		options := bson.M{
			"width": "100%",
			//"minRows": 4,
			"placeholder": "Please Input",
			//"maxRows": 6,
			"maxLength":    nil,
			"type":         "text",
			"defaultValue": "",
			"clearable":    false,
			"hidden":       false,
			"disabled":     false,
		}
		field := cgs_worksheet.Field{
			Name:     m["controlId"].(string),
			Alia:     m["controlName"].(string),
			DataType: "input",
			Options:  options,
		}
		fields = append(fields, &field)
	}
	return fields


}


func createFields(data bson.M) []bson.M {
	controls:=data["controls"].([]interface{})
	var fields []bson.M
	for _, v := range controls {
		m := v.(map[string]interface{})
		options := bson.M{
			"width": "100%",
			//"minRows": 4,
			"placeholder": "Please Input",
			//"maxRows": 6,
			"maxLength":    nil,
			"type":         "text",
			"defaultValue": "",
			"clearable":    false,
			"hidden":       false,
			"disabled":     false,
		}
		field := bson.M{
			"name":     m["controlId"],
			"alia":     m["controlName"],
			"dataType": 0,
			"options":  options,
		}
		fields = append(fields, field)
	}
	return fields
}
func createConfigStr(controls []interface{})string{
	config:=newConfig(controls)
	configStr, _ := json.Marshal(config)
	str := string(configStr)
	return str
}

func newConfig(controls []interface{}) interface{} {
	var wsconfig =make(map[string]interface{})
	var config=make(map[string]interface{})
	config["layout"]="horizontal"
	config["labelCol"]=map[string]interface{}{"xs":4,"sm":4,"md":4,"lg":4,"xl":4,"xxl":4}
	config["wrapperCol"]=map[string]interface{}{"xs":18,"sm":18,"md":18,"lg":18,"xl":18,"xxl":18}
	config["hideRequiredMark"]=false
	config["customStyle"]=""
	wsconfig["config"]=config
	var list=make([]interface{},len(controls))
	for ind,v :=range controls{
		var control=make(map[string]interface{})
		v1:=v.(map[string]interface{})
		control["type"]="input"
		control["label"]=v1["controlName"]
		options:=createOptions()
		control["options"]=options
		control["model"]=v1["controlId"]
		control["key"]=v1["controlId"]
		rules:=createRules()
		control["rules"]=rules
		list[ind]=control
	}
	wsconfig["list"]=list
	return wsconfig
}

func createRules() interface{} {
	var rules = make([]interface{},1)
	var rule=make(map[string]interface{})
	rule["required"]=false
	rule["message"]="必填项"
	rules[0]=rule
	return rules
}
func createOptions() map[string]interface{} {
	var options = make(map[string]interface{})
	options["type"] = "text"
	options["width"] = "100%"
	options["defaultValue"] = ""
	options["placeholder"] = "请输入"
	options["clearable"] = false
	options["maxLength"] = nil
	options["hidden"] = false
	options["disabled"] = false
	return options
}

func getBaseUrl(url string) string {
	vision := []string{"/v1/", "/v2/", "/v3/", "/v4/", "/v5/"}
	for _, s := range vision {
		if strings.Contains(url, s) {
			url = strings.Split(url, s)[0]
			break
		}
	}

	return url
}